package topic_service

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"fmt"
	ark "github.com/sashabaranov/go-openai"
	"io"
	"os"
	"strings"
	"video_demo/config"
	"video_demo/db"
	"video_demo/entity"
	"video_demo/tools"
)

// 文档文件处理
func processDocumentFile(file io.Reader, ext string, client *ark.Client) (interface{}, error) {
	content, err := tools.ConvertToText(file, ext)
	if err != nil {
		return nil, fmt.Errorf("文件读取失败: %w", err)
	}
	return callAIAPI(client, ark.ChatCompletionRequest{
		Model: config.SysConfig.AIModel.ThinkingModel,
		Messages: []ark.ChatCompletionMessage{
			createSystemMessage(),
			{
				Role:    ark.ChatMessageRoleUser,
				Content: content,
			},
		},
	})
}

// 图片文件处理
func processImageFile(file io.Reader, client *ark.Client) ([]entity.Topic, error) {
	content, err := tools.ConvertToJpeg(file)
	if err != nil {
		return nil, fmt.Errorf("图片读取失败: %w", err)
	}

	base64Img := base64.StdEncoding.EncodeToString(content)
	imgResult := createImageRequest(base64Img)

	rawResult, err := callAIAPI(client, imgResult)
	if err != nil {
		return nil, fmt.Errorf("大模型请求失败: %w", err)
	}

	/*jsonStr, ok := rawResult.(string)
	if !ok {
		return nil, fmt.Errorf("大模型返回格式异常 :%w", err)
	}*/

	var topics []entity.Topic
	if err := json.Unmarshal([]byte(rawResult), &topics); err != nil {
		return nil, fmt.Errorf("大模型返回格式JSON 解析失败: %w", err)
	}

	return topics, nil
}

// 公共AI请求方法
func callAIAPI(client *ark.Client, req ark.ChatCompletionRequest) (string, error) {
	resp, err := client.CreateChatCompletion(context.Background(), req)
	if err != nil {
		return "", fmt.Errorf("AI解析失败: %w", err)
	}
	return parseAIResponse(resp.Choices[0].Message.Content), nil
}

// 创建系统消息模板
func createSystemMessage() ark.ChatCompletionMessage {
	return ark.ChatCompletionMessage{
		Role: ark.ChatMessageRoleSystem,
		Content: "请将以下题目内容解析为结构化JSON数据，包含题目、选项、答案、难度、解析、知识点字段。如果无法解析，请返回错误信息。" +
			"下面是题目数据样例: 其中的answer字段是选项中对应的答案，例如{\"1\":\"11\"}的答案是\"11\") " +
			"{\"subject\":\"math\",\"type\":\"single\",\"question\":\"1+12\",\"options\":{\"1\":\"11\",\"2\":\"12\",\"3\":\"13\",\"4\":\"14\"},\"answer\":\"14\",\"difficulty\":\"easy\",\"knowledge\":\"1+1=2\",\"analyze\":\"1+1=2\"}" +
			"不要直接把ABCD的选择直接给我，answer字段我只要正确的结果值，而不是A,B,C,D的选项",
	}
}

// 创建图片解析请求
func createImageRequest(base64Img string) ark.ChatCompletionRequest {
	return ark.ChatCompletionRequest{
		Model: config.SysConfig.AIModel.VersionModel,
		Messages: []ark.ChatCompletionMessage{
			{
				Role: ark.ChatMessageRoleUser,
				MultiContent: []ark.ChatMessagePart{
					{
						Type: ark.ChatMessagePartTypeText,
						Text: "请将以下题目内容解析，包含题目、选项、答案、难度、解析、知识点字段。如果无法解析，请返回错误信息。" +
							"下面是题目数据样例: 其中的answer字段是选项中对应的答案，例如{'1':'11'}的答案是'11' " +
							"如果有题号的数据，不要解析题号，并将数据结构化成以下结构的数组形式" +
							"   {subject:math,type:single,question:question,options:{A:1,B:2,C:3},answer:3,difficulty:easy,knowledge:knowledge,analyze:analyze}    " +
							"单选题与多选题中的选项至少要有四个选项,原题不足补够四个选项,补全的选项值选择与已" +
							"不要直接把ABCD的选项直接映射成answer的值，answer字段我只要正确选项对应的结果，如选项{A:3,B:1,C:2}答案是C,映射的结果就是{'answer':'2'}，而不是A,B,C,D的选项",
					},
					{
						Type: ark.ChatMessagePartTypeImageURL,
						ImageURL: &ark.ChatMessageImageURL{
							URL: "data:image/jpeg;base64," + base64Img,
						},
					},
				},
			},
		},
	}
}

// 解析AI响应
func parseAIResponse(content string) string {
	cleanedContent := strings.ReplaceAll(content, "\\", "")
	cleanedContent = strings.ReplaceAll(cleanedContent, "```json", "")
	cleanedContent = strings.TrimSuffix(cleanedContent, "```")
	return cleanedContent
}

// 文档类型判断
func isDocumentFile(ext string) bool {
	documentTypes := map[string]bool{
		".pdf": true, ".txt": true, ".docx": true, ".doc": true,
		".xlsx": true, ".xls": true, ".pptx": true, ".ppt": true,
		".md": true, ".csv": true, ".mobi": true, ".epub": true,
	}
	return documentTypes[ext]
}

func processBatchQuestion(questions string) (string, error) {
	cfg := ark.DefaultConfig(os.Getenv("ARK_API_KEY"))
	cfg.BaseURL = config.SysConfig.AIModel.URL
	client := ark.NewClientWithConfig(cfg)
	resp, err := client.CreateChatCompletion(
		context.Background(),
		ark.ChatCompletionRequest{
			Model: "doubao-1.5-vision-lite-250315",
			Messages: []ark.ChatCompletionMessage{
				{
					Role: ark.ChatMessageRoleSystem,
					Content: "请将以下题目内容解析，包含题目、选项、答案、难度、解析、知识点字段。如果无法解析，请返回错误信息。" +
						"下面是题目数据样例: 其中的answer字段是选项中对应的答案，例如{'1':'11'}的答案是'11' ," +
						"如果有题号的数据，不要解析题号，并将数据结构化成以下结构的数组形式：" +
						"   {subject:math,type:single,question:question,options:{A:1,B:2,C:3},answer:3,difficulty:easy,knowledge:knowledge,analyze:analyze}    ," +
						"单选题与多选题中的选项至少要有四个选项,原题不足补够四个选项,补全的选项值选择与已," +
						"不要直接把ABCD的选项直接映射成answer的值，answer字段我只要正确选项对应的结果，如选项{A:3,B:1,C:2}答案是C,映射的结果就是{'answer':'2'}，而不是A,B,C,D的选项," +
						"解析出的结果中将frac,times,div等转义符转为对应的数学符号," +
						"subject对应的值{math,chinese,english},type对应的值{single,multiple,judgment},difficulty对应的值{easy,medium,hard},这三个字段值必须是全小写英文," +
						"请按照上面提供的格式给我正确的返回结果.",
				},
				{
					Role:    ark.ChatMessageRoleUser,
					Content: questions,
				},
			},
		},
	)
	if err != nil {
		return "", fmt.Errorf("AI解析失败: %w", err)
	}

	return resp.Choices[0].Message.Content, nil
}

func SaveBatchQuestions(topics []entity.Topic) error {
	for index := range topics {
		topics[index].ID = 0 // 清除ID，让gorm自动生成新的ID
	}

	base := db.GetDB()
	// 开启事务（保证原子性）
	tx := base.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	if err := tx.CreateInBatches(topics, 100).Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("数据库操作失败: %w", err)
	}

	return tx.Commit().Error
}
